/*
 * JaCoLiB
 * Copyright (C) 2008 Alessandro Serra
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

package it.gashale.jacolib.connection;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.logging.Logger;

public class Connection {
	protected static Logger logger=Logger.getLogger("conncetion");
	protected Socket socket;
	
	protected String str;
	
	protected BufferedReader in_strm;
	protected PrintStream out_strm;
	
	public Connection(Socket socket) throws IOException {
		this.socket=socket;
		in_strm=new BufferedReader(new InputStreamReader(socket.getInputStream(),"US-ASCII"));
		out_strm=new PrintStream(socket.getOutputStream(),true, "US-ASCII");
	}
	public Socket getSocket() {
		return socket;
	}
	
	public String getStr() {
		return str;
	}
	/*
	 * I/O
	 */
	public void write_simple_string(String s) {
		out_strm.print(s+"\n");
	}
	public String read_simple_string() throws IOException {
		String s=in_strm.readLine();
		logger.info("read: "+s);
		return s;
		
	}
	public void write_string(String s) {
		out_strm.print(s.length()+"\n");
		out_strm.print(s);
	}
	public String read_string() throws IOException {
		int numBytes=Integer.parseInt(in_strm.readLine());
		char[] buff = new char[numBytes];
        
		int num=0;
		while(num<numBytes) {
			num+=in_strm.read(buff, num, numBytes-num);
		}
        
        String s=new String(buff);
        logger.info("read: "+numBytes+"  "+s.substring(0, 10));
        return s;
	}
	/*
	 * 
	 */
	public void flush() {
		out_strm.flush();
	}
	public void close() throws IOException {
		write_simple_string("close");
		flush();
		socket.close();
	}
	/*
	 * 
	 */
	public void send_request(String req) {
		write_simple_string("req");
		write_string(req);
		flush();
	}
	public void send_response(String res) {
		write_simple_string("res");
		write_string(res);
		flush();
	}
	public void send_fatalerror_and_quit(String msg) throws IOException {
		write_simple_string("fatal-error");
		write_string(msg);
		flush();
		socket.close();
	}
	public String receive() {
		String s;
		try {
			s = read_simple_string();
			if(s==null) {
				socket.close();
				s="close";
			} else if (s.equals("close")) {
				socket.close();
			} else if(s.equals("res")) {
				str=read_string();
			} else if(s.equals("req")) {
				str=read_string();
			} else if(s.equals("fatal-error")) {
				str=read_string();
				socket.close();
			} else {
				s="fatal-error";
				str="expected close, res, req, or fata-error key";
				socket.close();
			}
		} catch (IOException e) {
			str=e.getMessage();
			s="fatal-error";
		}
		return s;
	}
}
